use crate::key_manager::error::KeyManagerError;
use crate::key_manager::lifecycle::key_observer::observer_init::register::OBSERVER_REGISTRY;
use crate::key_manager::lifecycle::key_subject::{KeyLifecycle };
use crate::key_manager::lifecycle::key_subject::KeySubject;
use crate::key_manager::web::key_by_http::DefaultKeyProvider;
use crate::key_manager::web::KeyProvider;
use lazy_static::lazy_static;
use mockall::automock;
use std::future::Future;
use std::sync::Mutex;
use crate::config::YamlConfigLoader;
use crate::key_manager::web::key_api_client::KeyApiClient;

lazy_static! {
    static ref IS_INITIALIZED: Mutex<bool> = Mutex::new(false);
}

fn set_initialized() {
    let mut flag = IS_INITIALIZED.lock().unwrap();
    *flag = true;
}

/**
 * 检查是否已初始化
 *
 * @return 是否已初始化
 */
pub fn is_initialized() -> bool {
    *IS_INITIALIZED.lock().unwrap()
}

/**
 * 密钥初始化接口
 */
#[automock]
pub trait KeyInitialization {
    /**
     * 初始化密钥
     *
     * @return 初始化结果
     */
    fn initialize(&mut self) -> impl Future<Output = Result<(), KeyManagerError>>;
}

#[derive(Debug)]
pub struct DefaultKeyInitialization {
    default_key_provider: DefaultKeyProvider,
    key_subject: KeySubject,
}

impl DefaultKeyInitialization {
    pub fn new(default_key_provider: DefaultKeyProvider, key_subject: KeySubject) -> DefaultKeyInitialization {
        Self {
            default_key_provider,
            key_subject,
        }
    }
}

/**
 * Initialize the default key. Invoke the vault interface to obtain the full key
 *
 */
impl KeyInitialization for DefaultKeyInitialization {
    async fn initialize(&mut self) -> Result<(), KeyManagerError> {
        // Get the full key rustful -> vault
        let keys = self.default_key_provider
            .get_keys()
            .await
            .map_err(|e| KeyManagerError::new(e.to_string()))?;
        // Key management watcher mode for key rotation
        let key_manager = &mut self.key_subject;
        // load watchers from the registry
        if let Some(registry) = OBSERVER_REGISTRY.get() {
            for observer in registry.lock().unwrap_or_else(|e| e.into_inner()).iter() {
                key_manager.attach(observer.clone());
            }
        }
        key_manager
            .perform_key_rotation(keys)
            .await
            .map_err(|e| KeyManagerError::new(e.to_string()))?;

        set_initialized();

        if !is_initialized() {
            panic!("Key initialization failed");
        }
        Ok(())
    }
}

pub async fn init_keys() -> Result<(), KeyManagerError> {
    let yaml_config_loader = Box::new(YamlConfigLoader);
    let key_api_client = Box::new(KeyApiClient::new());
    let default_key_provider = DefaultKeyProvider::new(yaml_config_loader, key_api_client);
    let key_subject = KeySubject::new();
    let mut init = DefaultKeyInitialization::new(default_key_provider, key_subject);
    init.initialize().await
}

#[cfg(test)]
#[allow(warnings)]
mod key_init_tests {
    use std::fmt::Debug;
    use mockall::mock;
    use super::*;
    use crate::key_manager::web::key_api_client::KeyApiClientTrait;
    use std::pin::Pin;
    use std::sync::Arc;
    use crate::config::{MockConfigLoader, YamlConfig};
    use crate::key_manager::lifecycle::key_observer::key_lifecycle_observer::MockKeyLifecycleObserver;
    use crate::key_manager::lifecycle::key_subject::MockKeyLifecycle;
    use crate::key_manager::model::{Algorithm, Encoding, KeyVersionModel, PrivateKey, VaultResponse, Version};

    mock! {
        pub KeyApiClient {}
        impl Debug for KeyApiClient {
            fn fmt<'a>(&self, f: &mut std::fmt::Formatter<'a>) -> std::fmt::Result {
                f.debug_struct("KeyApiClient")
                    .field("client", &"awc::Client")
                    .finish()
            }
        }

        impl KeyApiClientTrait for KeyApiClient {
            fn get_keys(&self, url: &str) -> Pin<Box<dyn Future<Output = Result<VaultResponse, Box<KeyManagerError>>>>>;
        }
    }
    
    mock! {
        pub DefaultKeyInitialization {}
        impl Debug for DefaultKeyInitialization {
            fn fmt<'a>(&self, f: &mut std::fmt::Formatter<'a>) -> std::fmt::Result {
                f.debug_struct("KeyApiClient")
                    .field("client", &"awc::Client")
                    .finish()
            }
        }
    }

    #[tokio::test]
    async fn test_initialize() {
        let mut key_lifecycle_observer = MockKeyLifecycleObserver::new();
        key_lifecycle_observer.expect_signature_update().returning(|_, _| Box::pin(async move { Ok(()) }));
        let mock_observer = Arc::new(key_lifecycle_observer);
        OBSERVER_REGISTRY.get_or_init(|| Mutex::new(Vec::new()));
        OBSERVER_REGISTRY.get().unwrap().lock().unwrap().push(mock_observer.clone());
        let mut mock_key_lifecycle = MockKeyLifecycle::new();
        mock_key_lifecycle.expect_perform_key_rotation().returning(move |_| Box::pin(async {Ok(())}));
        let mut mock_config_loader = MockConfigLoader::new();
        mock_config_loader.expect_load_config().returning(move || {Some(Box::new(YamlConfig {
            vault_get_key_url: "http://localhost:8081/v1/vault/get_signing_keys".to_string(),
        }))});
        let mut observer = MockKeyLifecycleObserver::new();
        observer.expect_signature_update().returning(|_, _| Box::pin(async move { Ok(()) }));
        let mut key_subject = KeySubject::new();
        key_subject.attach(Arc::new(observer));

        let mut mock_key_api_client = MockKeyApiClient::new();
        mock_key_api_client.expect_get_keys().returning(|_| {
            Box::pin(async {Ok(VaultResponse {
                ask: vec![],
                nsk: vec![],
                fsk: vec![KeyVersionModel {
                    version: Version::new("v3"),
                    private_key: PrivateKey("
-----BEGIN PRIVATE KEY-----
LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ3dxSnZsOTNjYVhhc1cKQXZBM2hiMkRzTFBvc1RZblhXT1dzUHkySWRiY1dva01nTVR0TWZjbTY5Smc4QVZXTU5idjE2bEFvaDRYaFduQwpLSElFdEthMld0MVhsKy9QV3pYSm16RFI0ZmNCempFYTRKdWNKeElWR1RmV0U0YUY5SmpZZUVhV1FNUnMwT3poClN5Sk54cWtrd0tOMnprQ3R1VWowZkNSNmc1M3ZFeFFpajhtaGYzWktLVW0rSVh5eVFBSFZwM2w3YWVUUWxIV08KSHk0Nk9rTEFHTjVmZWlaTFNYT1k4ais4clpYcUptcjVoWS9rRmV1dUlCZDA4UEdQVW43YnRhNE4zaFlYZ1F4OQpBU3Nna3ZsVTVobVpKN1FSSTdNbVZOSWMxUzMrT3A5TXFXWjdtY0RrUXJIM1FjTjdPSms4STdJR0xUZ2lTTmZICnRTZTVZSnkxQWdNQkFBRUNnZ0VBRjN5REpZTE9BZUpjSVpRSWJjbEpGZDREUFRkNk5LZVUydTd5MmlBTG1jWXIKbkU3dVgzNmFGa0daK2F0UGVsTUo4Rjhpc0dZZFRCRS9xMEdIVHhyWll6c1hYRkxsM2hLSlJ5RnJ6eXVVbEZmZQpiVzFaSXR5SzZlVXRhRGUyVmM3Y0YwTitWdkdMYTlBbS9oam9HYUVFMGM4T3JIZmxYM05Yd0xGVWhEbEZZUWhXCmxualV0Z3R2aVZXa3F3MWppOUtWZjh5MTBaUm5TUHhqQ292K215R3hGUkhXYWFqNHU1Y0VuQkU4MnIzazkrQ1IKNHRXMXRBT0Y1KzNFeC9VZXY5SjlOcmpxWTYwSFBLMHF5bGZudDVGRyttS21YbDBwcFJuZWN4QWtWeVV3dDVQOApLTHNOU21RR3hvamo3RXMwRVBxU1NuVDVXTUR4Ri9XQ3VrUVdIUStTd1FLQmdRRG1PVlJCOGl3bjZDWWFydmJuCmJRbmprN3BRV2l0MTV0VXJrVC9mSUdQT295K2M0R3BMUFdpWjczUkY3TCtNcXNyRXdyc2JqZkZtYjJKbFVmc3oKUmd4a3JMdkczVnplUERwUXFPYUdRUmtNdlp6M3NVaHZKOHJSNUVOYmlVeXM4S1piZlM0RmlSQWp4Rzl4TUoyWgpIb0FCUWVmSHhSRjVEVUk3QUw1NUV4cVdNUUtCZ1FERWIvNGVGNEhxMkhHS1RDR0xvSVpnOFNhY3k3ek9lckg2CmU5UUZwTTJMY3VJcEoyZnQ5WlpWUytNeWJrWURNNTU0TU40ZnlQVmRvQzNoNnpKc3FwdDd5RUZMNjcxejNLeTcKYm51Wno4bHFCNjR1cUNoZXE5WTc3bGZnNWlyZW83b09tL0RZU0JZNmFtOHlLd0VlR3RSSzJicit6TWR0SSs4Twp5SlhGY2ZSWnhRS0JnQ0hmNzVqZ2RFVE84TVJlV0RBSEtEeFhJVVB2Y0pPaGlsNGx1aHN2bmQvcXZQZTlRWWFlCm00U0M2ajNicnZlWXJjc3p4K292QVlVTUFKTmQ4N05BckZRbjRsMUpkdit3SnZoMVVhNFJhQWtxNFN6RTVoNk0KNFZmdTJVWmZ0bXQvNFVwMjZjMmd0RUkvQmhMR2ozblhOZ2g1VlF4YzM4eEsraUxLWWp4WVprSVJBb0dBSzlDMwpJOHNtaFZXRjdjMFJabTJGeTdXK1lSYm9wRDJsMlRNcGxhQ3U0RDNkeUVRcjRGMzVERW1EQWNxcS95ZlNYd2kzCll1dVdIeTROVGVrQ05FN1JvNGlGV0FQYkhDN0tzSHZ5UWRxaEdHOWlJTElOWHlDQkJwa2hMTjdxRFFNRUN5SXAKVkhTdjBKUFEvYVd0K0NNUDJ5bzVsWC9qczZwaU5pL3ppRGprd2VrQ2dZRUFwSVZjTGI2MmtaWWFFaHpHazBRQgpJejk0M3VxekR2YkQvdUxlemdHREFNN09UaEVFRlpkazBOQWwwbnNZV0RQaDJFVXJlSVJvcmx3RkFrVFBMMEw1Cmp3cnprS2RlSDcxemVBSldDWVpVSVhTRVk3Y1J3UEp4S3FKSG44NS9UUVBDdGhlelAwTGxPb0M4L2c2aWlaWmIKRkRNWEhyVjcvRXNRUXdUcjFadEYveWM9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
-----END PRIVATE KEY-----
".into()),
                    algorithm: Algorithm("rsa 3072 pss".into()),
                    encoding: Encoding("PEM".into()),
                }]
            })})
        });

        let default_key_provider = DefaultKeyProvider::new(Box::new(mock_config_loader), Box::new(mock_key_api_client));
        let mut key_initialization = DefaultKeyInitialization::new(default_key_provider, key_subject);
        println!("mock_config_loader.expect_load_config().returni");
        let restult = key_initialization.initialize().await;
        println!("restult = key_initializat");
        assert!(restult.is_ok());
        assert!(is_initialized());
    }
}
